package com.ck.mybatis.plus.util;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import com.ck.mybatis.plus.anotation.Fields;
import com.ck.mybatis.plus.entity.condition.ConditionVo;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * mybatisplus 的多条件查询帮助类
 * @author jiangqingpeng
 */
public class SearchMybatisPlusUtil {

    /**
     * 组装 mybatis-plus 的多条件查询，如果有in，between等则可在业务层自行处理
     * @param list
     * @return
     */
    public static QueryWrapper parseWhereSqlList(List<ConditionVo> list) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (CollectionUtils.isNotEmpty(list)) {
            for (ConditionVo conditionVo : list) {
                switch (conditionVo.getType()) {
                    //等于
                    case "eq":
                        queryWrapper.eq(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //不等于
                    case "ne":
                        queryWrapper.ne(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //模糊查询，like '%value%'
                    case "like":
                        queryWrapper.like(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //模糊查询，like '%value'
                    case "likeleft":
                        queryWrapper.likeLeft(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //模糊查询，like 'value%'
                    case "likeright":
                        queryWrapper.likeRight(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //模糊查询，not like '%value%'
                    case "notlike":
                        queryWrapper.notLike(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //大于
                    case "gt":
                        queryWrapper.gt(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //小于
                    case "lt":
                        queryWrapper.lt(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //大于等于
                    case "ge":
                        queryWrapper.ge(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //小于等于
                    case "le":
                        queryWrapper.le(CamelUtil.underscoreName(conditionVo.getColumn()), conditionVo.getValue());
                        break;
                    //in
                    case "in":
                        Object obj = conditionVo.getValue();
                        List<Object> objectList = castList( obj, Object.class );
                        queryWrapper.in(CamelUtil.underscoreName(conditionVo.getColumn()), objectList);
                        break;
                    //between
                    case "between":
                        Object objBetween = conditionVo.getValue();
                        List<Object> objectBetweenList = castList( objBetween, Object.class );
                        queryWrapper.between(CamelUtil.underscoreName(conditionVo.getColumn()),
                                objectBetweenList.get(0), objectBetweenList.get(1));
                        break;
                    default:
                        break;
                }
            }
        }
        return queryWrapper;
    }


    /**
     * 将 Object 对象转换成 list
     * @param obj
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<T>();
        if(obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }


    /**
     * object:前端传值对象，组装成 list
     * @param object
     * @return
     * @throws Exception
     */
    public static List<ConditionVo> sqlWhereDo(Object object) throws Exception {
        List<ConditionVo> list = new ArrayList<>();
        if( object != null ){
            // 拿到该类
            Class<?> clz = object.getClass();

            //获取包含父类的所有属性
            List<Field> fieldList = QueryUtil.getFiledsInfo( clz.getName() );

            // 获取实体类的所有属性，返回Field数组
            //Field[] fields = clz.getDeclaredFields(); //只获取本类中的所有属性
            for (Field field : fieldList) {
                //为私有属性放行
                field.setAccessible(true);

                //field.getName() 为属性名，例如：id，name等

                Field f = field;

                //获取属性在Fields注解的值，例如：eq，like等
                Fields anno = f.getAnnotation(Fields.class);
                if( anno != null ){
                    String value = anno.value();
                    //获取该属性的值（由前端传过来的值）
                    Object objValue = field.get(object);
                    if (StringUtils.isNotBlank(value)) {
                        ConditionVo conditionVo = new ConditionVo();
                        conditionVo.setType(value);
                        conditionVo.setColumn(field.getName());
                        if( objValue != null ){
                            conditionVo.setValue(objValue);
                            list.add( conditionVo );
                        }
                    }
                }
            }
        }
        return list;
    }

}
